<?php

class ActivitySevenEventService extends AbstractService
{
    /**
     * @var ActivitySevenEventService
     */
    private static $instance;

    /**
     * Get the instance of ActivitySevenEventService.
     *
     * @return ActivitySevenEventService
     */
    public static function get()
    {
        if (!self::$instance) {
            self::$instance = new ActivitySevenEventService();
        }
        return self::$instance;
    }

    /**
     * Construction.
     */
    protected function __construct()
    {
        parent::__construct();
    }

    /**
     * 处理用户创建时的逻辑
     *
     * @param int $shardId
     * @return void
     */
    public function handleCreate($shardId)
    {

    }

    /**
     * 处理用户登录时的逻辑
     *
     * @param int $userId
     * @return void
     */
    public function handleLogin($userId)
    {
        // do nothing
    }

    /**
     * 处理 service 对外提供的全量数据
     *
     * @param int $userId
     * @return array
     */
    public function info($userId)
    {
        $sevenEventList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_ACTIVITY_SEVEN_EVENT);
        return [
            $sevenEventList
        ];
    }

    /**
     * 刷新7日签到活动
     * @param int $userId
     * @param int $indexId
     * @param int $endTime
     * @param int $reqTime
     * @return SzAbstractVoList
     * @throws SzException
     */
    public function flush($userId, $indexId, $endTime, $reqTime)
    {
        $sevenEventSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_SEVEN_EVENT, null, true);
        /**
         * @var ActivitySevenEventVo $sevenEvent
         */
        $sevenEventList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_ACTIVITY_SEVEN_EVENT);
        $sevenEvent = $sevenEventList->getElement($indexId, false);
        if ($sevenEvent) {
            if (!isset($sevenEventSettings[$indexId])) {
                $sevenEventList->deleteElement($indexId);
            } else if ($endTime <= $reqTime) {
                $totalDay = count($sevenEventSettings[$indexId]['award']);
                if ($sevenEvent->getStartTime() + SzTime::HOURS24 * $totalDay < $reqTime) {
                    $sevenEventList->deleteElement($indexId);
                }
            }
        } else if (isset($sevenEventSettings[$indexId]) && $endTime > $reqTime) {
            $sevenEvent = new ActivitySevenEventVo($userId, $indexId, SzTime::getTimestamp(SzTime::getDate($reqTime)), GameConst::DEFAULT_JSON_STRING, true);
            $sevenEventList->addElement($sevenEvent);
            $sevenEventList->setElement($indexId, $sevenEvent);
        }
        SzPersister::get()->setVoList($sevenEventList);
        return $sevenEventList;
    }

    /**
     * 七日签到活动的签到和补签
     * @param int $userId
     * @param int $indexId
     * @param int $isFree 1: 普通签到 2：补签
     * @param int $reqTime
     * @return bool
     * @throws SzException
     */
    public function signed($userId, $indexId, $isFree, $reqTime)
    {
        /**
         * @var ActivitySevenEventVo $sevenEvent
         */
        $sevenEventList = SzPersister::get()->getVoList($userId, GameConst::ORM_NAME_ACTIVITY_SEVEN_EVENT);
        $sevenEvent = $sevenEventList->getElement($indexId);
        $diff = GameService::get()->diffDate($reqTime, $sevenEvent->getStartTime());
        if (!$isFree) {//补签只能补签昨天的
            --$diff;
            $action = 'resign';
            $item = 'sign_7days';
        } else {
            $action = 'sign';
            $item = 'sign_resign';
        }
        $signedDay = $sevenEvent->getRawSignedDay();
        if ($diff < 0 || in_array($diff, $signedDay)) {
            throw new SzException(22101, [$indexId, $diff]);
        }
        $sevenEventSettings = SzConfig::get()->loadAppConfig(GameConst::CONFIG_GAME_SEVEN_EVENT, $indexId, true);
        if (!isset($sevenEventSettings['award'][$diff])) {
            throw new SzException(22102, [$indexId, $diff]);
        }
        $inputTid = '';
        if (!$isFree) {//补签消耗
            foreach ($sevenEventSettings['retroactive'][$diff] as $entityId => $count) {
                GameService::get()->handleEntity($userId, $entityId, $count, true);
                $inputTid .= $entityId . ':' . $count . '|';
            }
            CommonFunctionService::get()->reportResourceUseDetails(GameConst::FUNC_ACTIVITY_SHARE,$userId,0,$inputTid,'signed');//消耗资源上报
        }
        $signedDay[] = $diff;
        $sevenEvent->setSignedDay($signedDay);
        $sevenEventList->updateElement($indexId, $sevenEvent);
        SzPersister::get()->setVoList($sevenEventList);

        $tid = '';
        foreach ($sevenEventSettings['award'][$diff] as $entityId => $count) {
            GameService::get()->handleEntity($userId, $entityId, $count, true);
            $tid .= $entityId . ':' . $count . '|';
        }
        CommonFunctionService::get()->reportResourceUseDetails(GameConst::FUNC_ACTIVITY_SHARE,$userId,1,$tid,'signed');//消耗资源上报

        // 数据采集:签到领取奖励/补签领取奖励
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_USER_ORBIT, array(
            'clientData' => array(
                'tid' => 'Module:sign|action:' . $action . '|',
                'item' => $diff + 1,
                'value' => 1
            )
        ));

        // 数据采集:签到领取奖励产出/补签领取奖励产出
        StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_RESOURCE_OUTPUT, array(
            'clientData' => array(
                'tid' => $tid,
                'item' => $item . '&' . ($diff + 1)
            )
        ));

        if ($inputTid) {
            // 数据采集:补签消耗
            StatisticsService::get()->saveLog($userId, GameConst::LOG_TYPE_RESOURCE_OUTPUT, array(
                'clientData' => array(
                    'tid' => $inputTid,
                    'item' => $item . '&' . ($diff + 1)
                )
            ));
        }
        return true;
    }
}